package net.dreamlu.utils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import net.dreamlu.config.Consts;
import net.dreamlu.kit.ImageKit;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

import com.baidu.inf.iis.bcs.BaiduBCS;
import com.baidu.inf.iis.bcs.auth.BCSCredentials;
import com.baidu.inf.iis.bcs.model.ObjectListing;
import com.baidu.inf.iis.bcs.model.ObjectMetadata;
import com.baidu.inf.iis.bcs.model.ObjectSummary;
import com.baidu.inf.iis.bcs.model.X_BS_ACL;
import com.baidu.inf.iis.bcs.request.CreateBucketRequest;
import com.baidu.inf.iis.bcs.request.ListObjectRequest;
import com.baidu.inf.iis.bcs.request.PutObjectRequest;
import com.baidu.inf.iis.bcs.response.BaiduBCSResponse;

/**
 * 百度云储存上传
 * @author L.cm
 * @date 2013-5-22 下午2:19:05
 * BAE 常用服务：<url> http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/demo</url>
 */
public class BCSUtils {

    private static final Logger logger = Logger.getLogger(BCSUtils.class);
    // ----------------------------------------
    public static final String IMG_TYPE = ".jpg|.jepg|.gif|.png|.bmp";
    public static final String ALL_TYPE = ".jpg|.jepg|.gif|.png|.bmp|.gz|.rar|.zip|.pdf|.txt|.swf|.wmv";

    public static String bucket = ConfigUtil.get("bucket");
    public static boolean hasBucket = false;

    /**
     * 初始化BaiduBCS
     * @param @return    设定文件
     * @return BaiduBCS    返回类型
     * @throws
     */
    private static BaiduBCS getBaiduBCS (){
        BCSCredentials credentials = new BCSCredentials(Consts.AK, Consts.SK);
        BaiduBCS baiduBCS = new BaiduBCS(credentials, "bcs.duapp.com");
        baiduBCS.setDefaultEncoding("UTF-8"); // Default UTF-8 
        return baiduBCS;
    }

    /**
     * 获取文件类型
     * @param @param fileName
     * @param @return    设定文件
     * @return String    返回类型
     * @throws
     */
    public static String getFileType(String fileName){
        return fileName.substring(fileName.lastIndexOf("."), fileName.length());
    }
    
    /**
     * 检查文件类型
     * @param @param fileName
     * @param @param isImg
     * @param @return    设定文件
     * @return boolean    返回类型
     * @throws
     */
    public static boolean checkFileType(String fileName, boolean isImg) {
        String fileType = getFileType(fileName);
        if (isImg) {
            return IMG_TYPE.indexOf(fileType.toLowerCase()) == -1;
        } else {
            return ALL_TYPE.indexOf(fileType.toLowerCase()) == -1;
        }
    }
    
    /**
     * 新建一个公开的 bucket
     * @param @param baiduBCS    设定文件
     * @return void    返回类型
     * @throws
     */
    private static void createBucket(BaiduBCS baiduBCS) {
        if (!hasBucket) {
            try {
                baiduBCS.createBucket(new CreateBucketRequest(bucket, X_BS_ACL.PublicRead));
            } catch (Exception e) {
                logger.error(e);
                hasBucket = true;
            }
        }
    }
    
    /**
     * bcs-sdk-java_1.4.3.zip
     * 
     * url: http://developer.baidu.com/wiki/index.php?title=docs/cplat/stor/sdk
     * 
     * 说明 更多的 请根据 /bcs-sdk-java_1.4.3/sample/Sample.java 更改
     */
    
    /**
     * 直接上传文件 
     * @param @param file
     * @param @return    设定文件
     * @return boolean    返回类型
     * @throws
     */
    public static boolean uploadByFile (File file, String fileName) throws Exception {
        BaiduBCS baiduBCS = getBaiduBCS();
        createBucket(baiduBCS);
        String object = "/" + fileName;
        PutObjectRequest request = new PutObjectRequest(bucket, object, file);
        ObjectMetadata metadata = new ObjectMetadata();
        // 设置成公开读
        request.setAcl(X_BS_ACL.PublicRead);
        request.setMetadata(metadata);
        BaiduBCSResponse<ObjectMetadata> response = baiduBCS.putObject(request);
        ObjectMetadata objectMetadata = response.getResult();
        logger.info("x-bs-request-id: " + response.getRequestId());
        logger.info(objectMetadata);
        return true;
    }
    
    /**
     * 百度云文件上传
     * @param @param content
     * @param @param contentType
     * @param @param length
     * @param @param last
     * @param @return    设定文件
     * @return boolean    返回类型
     * @throws
     */
    public static boolean uploadByInputStream(InputStream content, String contentType, long length, String fileName) throws Exception {
        BaiduBCS baiduBCS = getBaiduBCS();
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(contentType);
        objectMetadata.setContentLength(length);
        // 设置成公开读
        objectMetadata.setHeader("x-bs-acl", "public-read");
        String object = "/" + fileName;
        PutObjectRequest request = new PutObjectRequest(bucket, object, content, objectMetadata);
        ObjectMetadata result = baiduBCS.putObject(request).getResult();
        logger.info(result.getContentMD5());
        logger.info(result);
        return true;
    }

    /**
     * 列出所有的
     * @param @return    设定文件
     * @return List<String>    返回类型
     * @throws
     */
    public static List<String> listObject(int size) {
    	BaiduBCS baiduBCS = getBaiduBCS();
        List<String> retList = new ArrayList<String>();
        ListObjectRequest listObjectRequest = new ListObjectRequest(bucket);
        listObjectRequest.setStart(0); // 查询 0～size
        listObjectRequest.setLimit(size);
        // 获取list
        BaiduBCSResponse<ObjectListing> response = baiduBCS.listObject(listObjectRequest);
        for (ObjectSummary os : response.getResult().getObjectSummaries()) {
        	String imgs = os.getName();
        	boolean isFail = BCSUtils.checkFileType(imgs, true);
        	if (!isFail) {
        		retList.add("http://bcs.duapp.com/" + BCSUtils.bucket + os.getName());
        	}
        }
        return retList;
    }
    
    /**
     * 上传文件
     * @param @param file
     * @param @param fileName
     * @param @return
     * @param @throws Exception    设定文件
     * @return String    返回类型
     * @throws
     */
    public static String upload(File file, String fileName) throws Exception{
        String fileType = getFileType(fileName);
        logger.info(fileType);
        String newName = System.currentTimeMillis() + fileType;
        logger.info(newName);
        uploadByFile(file, newName);
        return "http://bcs.duapp.com/" + BCSUtils.bucket + "/" + newName;
    }
    
    /**
     * 上传base64图片,并水印
     * @param @return    设定文件
     * @return String    返回类型
     * @throws
     */
    public static String uploadBase64(String string, String newName) throws Exception{
    	byte[] bytes = Base64.decodeBase64(string);
		for (int i = 0; i < bytes.length; ++i) {
			if (bytes[i] < 0) {
				bytes[i] += 256;
			}
		}
		BCSUtils.uploadByInputStream(new ByteArrayInputStream(bytes), "image/jpeg", bytes.length, newName);
		String url = "http://bcs.duapp.com/" + BCSUtils.bucket + "/" + newName;
		byte[] bs = ImageKit.watermark(url, Consts.DOMAIN_NAME); // 水印域名
        // 第二次水印之后重新上传
        uploadByInputStream(new ByteArrayInputStream(bs), "image/jpeg", bs.length, newName);
        return url;
    }
    
    /**
     * 上传并水印
     * @param @param file
     * @param @param fileName
     * @param @return    设定文件
     * @return String    返回类型
     * @throws
     */
    public static String uploadWatermark(File file, String fileName) throws Exception {
        String fileType = getFileType(fileName);
        String newName = System.currentTimeMillis() + fileType;
        uploadByFile(file, newName);
        String url = "http://bcs.duapp.com/" + BCSUtils.bucket + "/" + newName;
        byte[] bs = ImageKit.watermark(url, Consts.DOMAIN_NAME); // 水印域名
        // 第二次水印之后重新上传
        uploadByInputStream(new ByteArrayInputStream(bs), "image/jpeg", bs.length, newName);
        return url;
    }
}
